package com.fattyCorps.service;

import com.fattyCorps.cache.PlayerCache;
import com.fattyCorps.cache.packet.PacketMap;
import com.fattyCorps.config.gameConfig.GlobalConfig;
import com.fattyCorps.config.gameConfig.HeroConfig;
import com.fattyCorps.exception.gameException.hero.*;
import com.fattyCorps.obj.cache.PlayerInfo;
import com.fattyCorps.obj.cache.player.packet.Hero;
import com.fattyCorps.obj.mould.HeroMould;
import com.fattyCorps.obj.msg.SRet;
import com.fattyCorps.obj.msg.server.hero.SGetHeroListMsg;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Slf4j
public class HeroService {

    @Autowired
    PlayerCache playerCache;

    @Autowired
    HeroConfig heroConfig;

    @Autowired
    ItemService itemService;

    @Autowired
    GlobalConfig globalConfig;

    // 创建英雄
    public void createHero(Integer playerId, Integer typeId){
        HeroMould heroMould = heroConfig.getHeroMould(typeId);
        if (heroMould==null){
            throw new HeroMouldIdErrorException();
        }

        Hero hero = Hero.makeHero(heroMould, typeId);

        // 增加数据到内存
        PlayerInfo playerInfo = playerCache.getPlayerInfo(playerId);
        playerInfo.getPlayerData().getHeroes().put(hero);
    }


    // 获取英雄列表
    public SRet getHeroList(Integer playerId){
        PlayerInfo playerInfo = playerCache.getPlayerInfo(playerId);
        List<Hero> heroes = playerInfo.getPlayerData().getHeroes().getElems();
        SGetHeroListMsg sGetHeroListMsg = new SGetHeroListMsg();
        sGetHeroListMsg.setHeroList(heroes);
        return SRet.success(sGetHeroListMsg);
    }

    // 升级
    public SRet<Hero> lvUp(Integer playerId, Integer heroId){
        Hero hero = getHero(playerId, heroId);

        // 每星提升20级等级上限
        Integer maxLv = hero.getStar() * globalConfig.getIntValue(GlobalConfig.STAR_LV);
        if (hero.getLv()>=maxLv){
            throw new HeroLvMaxErrorException();
        }

        // todo:判断道具是否够，执行后续道具逻辑
        Integer needExpItemNum = hero.getLv()*100;
        Integer expItemTypeId = globalConfig.getIntValue(GlobalConfig.EXP_ITEM_TYPE_ID);
        boolean b = itemService.delItemByTypeId(playerId, expItemTypeId, needExpItemNum);
        if (!b){
            throw new HeroExpNotEnoughErrorException();
        }

        HeroMould heroMould = heroConfig.getHeroMould(hero.getTypeId());

        hero.setLv(hero.getLv() + 1);
        hero.setAtt(hero.getAtt() + heroMould.getLvUpAtt());
        hero.setDef(hero.getDef() + heroMould.getLvUpDef());
        hero.setMaxHp(hero.getMaxHp() + heroMould.getLvUpMaxHp());

        return SRet.success(hero);
    }


    // 升星
    public SRet<Hero> starUp(Integer playerId, Integer heroId, Integer consumeHeroId1, Integer consumeHeroId2, Integer consumeHeroId3) {
        Hero hero = getHero(playerId, heroId);

        Integer maxStar = globalConfig.getIntValue(GlobalConfig.MAX_STAR);
        if (hero.getStar()>=maxStar){
            throw new HeroStarMaxErrorException();
        }

        // todo:判断道具是否够，执行后续道具逻辑
        Integer needStarStoneItemNum = hero.getStar()*10;
        Integer starStoneItemTypeId = globalConfig.getIntValue(GlobalConfig.STAR_STONE_ITEM_TYPE_ID);
        boolean b = itemService.delItemByTypeId(playerId, starStoneItemTypeId, needStarStoneItemNum);
        if (!b){
            throw new HeroStarStoneNotEnoughErrorException();
        }

        // 判断英雄是否足够，要消耗一个同星本体，以及两个同星狗粮
        Hero heroConsume1 = getHero(playerId, consumeHeroId1);
        Hero heroConsume2 = getHero(playerId, consumeHeroId2);
        Hero heroConsume3 = getHero(playerId, consumeHeroId3);
        if (heroConsume1.getTypeId()!=hero.getTypeId() || heroConsume1.getStar()!=hero.getStar() ||
                heroConsume2.getStar()!=hero.getStar() || heroConsume3.getStar()!=hero.getStar()){
            throw new HeroStarUpMaterialErrorException();
        }

//        // 删除数据库英雄信息
//        try {
//            heroMapper.deleteById(consumeHeroId1);
//            heroMapper.deleteById(consumeHeroId2);
//            heroMapper.deleteById(consumeHeroId3);
//        }catch (Exception e){
//            log.error("starUp error: playerId=" + playerId+ " heroId="+heroId+ " consumeHeroId1="+consumeHeroId1+ " consumeHeroId2="+consumeHeroId2+ " consumeHeroId3="+consumeHeroId3);
//            throw new HeroStarUpDelErrorException();
//        }

        // 删除内存英雄信息
        PacketMap<Hero> heroes = getPacketHero(playerId);
        heroes.remove(heroConsume1.getId());
        heroes.remove(heroConsume2.getId());
        heroes.remove(heroConsume3.getId());

        // 修改内存，为hero升星
        hero.setStar(hero.getStar() + 1);
        heroes.put(hero);

        return SRet.success(hero);
    }

    private Hero getHero(Integer playerId, Integer heroId){
        PlayerInfo playerInfo = playerCache.getPlayerInfo(playerId);
        return playerInfo.getPlayerData().getHeroes().get(heroId);
    }

    public PacketMap<Hero> getPacketHero(Integer playerId) {
        return playerCache.getPlayerInfo(playerId).getPlayerData().getHeroes();
    }
}
